Today, many devices are controlled by software. To support the development of software for such a wide array of devices, many programming languages have been developed. Programming languages support constructs that allow users to write a program in a format that is understandable to a person. Programs in this format are said to be in “source code” form. A compiler is used to convert a program in source code form into a form in which it can be executed by a computer.
Each programming language may include features that make it easy for a user to write programs. These features allow a user to express in a small number of high level instructions what could be potentially a very large number of computations or manipulations that a computer is to perform when the software is executed.
In some cases, a programming language may be object-oriented. Such a language allows a user to define objects. Using objects allows an overall program to be segregated into logical pieces that a programmer, or group of programmers, can conveniently develop. In addition, the overall program can be created by specifying interactions between the objects, which, because the objects can be defined based on logical elements meaningful to a human programmer, is also likely to be convenient for a human programmer.
Each object may have methods and properties. The methods represent operations, sometimes called functions or procedures, that can be used to interact with the object. The properties define states or identities associated with the object in an execution environment.
Some programming languages also support “types.” As a program is developed, any element that may take on a value during execution of the program may be given a type. For example, when a variable that is intended to represent a numeric quantity is declared, it may be assigned a type appropriate for the type of number it is to represent. The use of types can help a compiler efficiently store and operate on values. For example, the compiler can specify a simpler sequence of instructions to perform mathematical operations on variables that are declared to be integers or natural numbers than the same operations that are performed on variables that could be floating point numbers. Moreover, a compiler may allocate less storage space for a variable declared to have an integer type than for a variable declared to be a floating point number.
While having typing can lead to more efficient programs, it can limit flexibility for programmers. Dynamic languages are intended to simplify the development of programs. Rather than requiring a programmer to declare a type of each variable, in a dynamic language, the compiler determines the types of variables based on how they are used. To support this capability, a compiler for a dynamic language may contain type inference rules for types that are defined as part of the dynamic language. As the compiler processes objects in a source program that generate values, it applies the type inference rules to determine the appropriate type for representing the generated value.